package com.demo.search;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.search.highlight.TokenSources;
import org.apache.lucene.search.similar.MoreLikeThis;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

/**
 * 同音词、同义词、近义词检索Demo
 * 
 * @author ryuu.kk
 */
public class SynonymDemo {
	
	public static void main(String[] args) throws CorruptIndexException, LockObtainFailedException, IOException, ParseException, InvalidTokenOffsetsException {
		
		SynonymDemo demo = new SynonymDemo();
		demo.testKoolKat();
		
				int a=1;
				int b=3;
				a^=b;
				b^=a;
				a^=b;
				System.out.println("a:" + a);System.out.println("b:" + b);
			
	}
	
	public void testKoolKat() throws CorruptIndexException, LockObtainFailedException, IOException, ParseException, InvalidTokenOffsetsException {
		RAMDirectory directory = new RAMDirectory();
		//Directory directory = FSDirectory.open(new File("C:\\development\\lucence\\index"));
		//IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_36, new StandardAnalyzer(Version.LUCENE_36));
		// 近义词分析器
		Analyzer analyzer = new MetaphoneReplacementAnalyzer();
		IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_36, analyzer);
		IndexWriter writer = new IndexWriter(directory, writerConfig);
		// 建立索引
		Document doc = new Document();
		doc.add(new Field("title", "author ryuu.kk", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
		doc.add(new Field("contents", "the cool cat jump over the lazy dog. Java编程语言  计算机 author ", Field.Store.YES, Field.Index.ANALYZED));
		//writer.addDocument(doc);
		
		doc.add(new Field("title", "author ryuu.kk", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
		doc.add(new Field("contents", " Java编程语言  计算机 author", Field.Store.YES, Field.Index.ANALYZED));
		writer.addDocument(doc);
		
		writer.close();
		
		//
		IndexReader indexReader = IndexReader.open(directory);
		
		// 索引快照
		IndexReader newReader = IndexReader.openIfChanged(indexReader);
		if (newReader != null) {
			indexReader.close();
			indexReader = newReader;
		}
		IndexSearcher searcher = new IndexSearcher(indexReader);
		
		System.out.println("\n---------------------  这是一个同音词的检索例子   ---------------------------");
		// 同音词检索kool kat与cool cat读音相同,则cool cat将被检索出
		Query query = new QueryParser(Version.LUCENE_36, "contents", analyzer).parse("kool kat");
		
		// Query query = IKQueryParser.parse("contents", "kool kat");
		TopDocs hits = searcher.search(query, 1);
		
		int docID = hits.scoreDocs[0].doc;
		
		// -------------------------------------------------------------------------------------------------
		// 测试一下类似文档检索：1.需要原始docID; 2.需要得到查询的索引indexReader; 3.需要查询Query
		MoreLikeThis mlt = new MoreLikeThis(indexReader);
		mlt.setFieldNames(new String[] { "author" });
		mlt.setMinTermFreq(1);  //默认值是2，建议自己做限制，否则可能查不出结果
		mlt.setMinDocFreq(1);   //默认值是5，建议自己做限制，否则可能查不出结果

		Document docTmp = indexReader.document(docID);
		System.out.println(docTmp.get("title"));
		Query queryTmp = mlt.like(docID);
		System.out.println("  query like ：" + queryTmp);
		
		TopDocs sililarDocs = searcher.search(queryTmp, 10);
		for (int i = 0; i < sililarDocs.scoreDocs.length; i ++) {
			docTmp = indexReader.document(sililarDocs.scoreDocs[i].doc);
			System.out.println("  -> " + docTmp.getFieldable("contents").stringValue());
		}
		//-------------------------------------------------------------------------------------------------
		
		//XmlQueryParser xmlParser = new XmlQueryParser();
		
		
		doc = searcher.doc(docID);
		String result = doc.get("contents") ;
				
		System.out.println("\n检索参数 【kool kat】  -> 检索结果 【 " + doc.get("contents") + "】");
		searcher.close();
		
		System.out.println("\n---------------------  这是一个同义词的检索例子   ---------------------------");
	}
}
